package io.dcloud.uniplugin

import TCPClient
import android.util.Base64
import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNotNull
import junit.framework.TestCase.assertTrue
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException
import java.net.ServerSocket
import java.nio.charset.Charset
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

/**
 * TCP 客户端仪器化测试类
 * 测试 TCP 连接、数据发送接收等功能
 */
@RunWith(AndroidJUnit4::class)
class TCPClientTest {
    private lateinit var tcpClient: TCPClient
//    private lateinit var testServer: TestServer
    private val TAG = "TCPClientTest"
    private val TEST_IP = "192.168.1.228" // 使用本地回环地址
//    private val TEST_IP = "127.0.0.1" // 使用本地回环地址
    private val TEST_PORT = 9001
    private val TIMEOUT = 5000L // 5秒超时

    // 初始化测试环境
    @Before
    fun setup() {
        tcpClient = TCPClient()
//        testServer = TestServer(TEST_PORT)
//        testServer.start()
    }

    // 清理测试环境
    @After
    fun teardown() {
        tcpClient.disconnect()
//        testServer.stop()
    }

    @Test
    fun testTcpConnection() {
        val connectedLatch = CountDownLatch(1)
        val disconnectedLatch = CountDownLatch(1)

        // 设置状态监听器
        tcpClient.setStatusListener(object : TCPClient.OnStatusListener {
            override fun onStatus(isConnected: Boolean, error: String?) {
                if (isConnected) {
                    Log.d(TAG, "测试: 连接成功")
                    connectedLatch.countDown()
                } else {
                    Log.d(TAG, "测试: 连接断开")
                    disconnectedLatch.countDown()
                }
            }
        })

        // 连接到测试服务器
        tcpClient.connect(TEST_IP, TEST_PORT, 1000)

        // 等待连接成功
        assertTrue("连接超时", connectedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))

        // 断开连接
        tcpClient.disconnect()

        // 等待断开连接
        assertTrue("断开连接超时", disconnectedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))
    }

    @Test
    fun testSendAndReceiveString() {
        val dataReceivedLatch = CountDownLatch(1)
        val testData = "Hello, TCP Client!"
        var receivedData: String? = null

        // 设置数据监听器
        tcpClient.setByteArrayListener(object : TCPClient.OnByteArrayListener {
            override fun onByteArray(bytes: ByteArray?) {
                if (bytes != null) {
                    receivedData = String(bytes, Charset.forName("UTF-8"))
                    dataReceivedLatch.countDown()
                }
            }
        })

        // 连接到测试服务器
//        connectAndWait()
        tcpClient.connect(TEST_IP, TEST_PORT, 1000)
        // 发送字符串数据
        val bytes = testData.toByteArray(Charset.forName("UTF-8"))
        tcpClient.sendData(bytes)

        // 等待数据接收
        assertTrue("接收数据超时", dataReceivedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))

        // 验证接收数据
        assertNotNull("收到的数据为空", receivedData)
        assertEquals("数据不匹配", testData, receivedData)
    }

    @Test
    fun testSendAndReceiveHex() {
        val dataReceivedLatch = CountDownLatch(1)
        val testHex = "48656C6C6F2C2054435020436C69656E7421" // "Hello, TCP Client!"
        var receivedHex: String? = null

        // 增强监听器日志
        tcpClient.setByteArrayListener(object : TCPClient.OnByteArrayListener {
            override fun onByteArray(bytes: ByteArray?) {
                if (bytes != null) {
                    receivedHex = tcpClient.byteArrayToHexString(bytes)
                    Log.d("Test", "【测试监听器】收到数据：$receivedHex")
                    dataReceivedLatch.countDown()
                }
            }
        })

        // 确保连接成功（同步等待）
//        connectAndWait()
        tcpClient.connect(TEST_IP, TEST_PORT, 1000)
        // 发送数据并记录
        val bytes = tcpClient.hexStringToByteArray(testHex)
        Log.d("Test", "【测试用例】发送数据：$testHex")
        tcpClient.sendData(bytes)

        // 增加等待时间并分阶段等待
        Log.d("Test", "【测试用例】等待接收数据...")
        val isTimeout = !dataReceivedLatch.await(15, TimeUnit.SECONDS)
        if (isTimeout) {
            Log.e("Test", "【测试用例】首次接收超时，尝试重新发送")
            tcpClient.sendData(bytes) // 重试发送
            assertTrue("第二次接收超时", dataReceivedLatch.await(10, TimeUnit.SECONDS))
        }

        // 验证
        assertNotNull("收到的数据为空", receivedHex)
        Log.d("Test", "【测试用例】验证数据：$receivedHex vs $testHex")
        assertEquals("十六进制数据不匹配", testHex, receivedHex)
    }
    @Test
    fun testSendAndReceiveBase64() {
        val dataReceivedLatch = CountDownLatch(1)
        val testData = "Hello, TCP Client!"
        val testBase64 = Base64.encodeToString(testData.toByteArray(), Base64.DEFAULT)
        var receivedBase64: String? = null

        // 设置数据监听器
        tcpClient.setByteArrayListener(object : TCPClient.OnByteArrayListener {
            override fun onByteArray(bytes: ByteArray?) {
                if (bytes != null) {
                    receivedBase64 = Base64.encodeToString(bytes, Base64.DEFAULT)
                    dataReceivedLatch.countDown()
                }
            }
        })

        // 连接到测试服务器
//        connectAndWait()
        tcpClient.connect(TEST_IP, TEST_PORT, 1000)
        // 发送 Base64 数据
        val bytes = testData.toByteArray(Charset.forName("UTF-8"))
        tcpClient.sendData(bytes)

        // 等待数据接收
        assertTrue("接收 Base64 数据超时", dataReceivedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))

        // 验证接收数据
        assertNotNull("收到的 Base64 数据为空", receivedBase64)
        assertEquals("Base64 数据不匹配", testBase64, receivedBase64)
    }

    @Test
    fun testConnectionTimeout() {
        val timeoutLatch = CountDownLatch(1)
        val nonExistentPort = 9999 // 不存在的端口

        // 设置状态监听器
        tcpClient.setStatusListener(object : TCPClient.OnStatusListener {
            override fun onStatus(isConnected: Boolean, error: String?) {
                if (!isConnected && error != null && error.contains("timeout")) {
                    timeoutLatch.countDown()
                }
            }
        })

        // 连接到不存在的端口
        tcpClient.connect(TEST_IP, nonExistentPort, 1000)

        // 等待超时
        assertTrue("连接超时测试失败", timeoutLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))
    }



    // 辅助方法：连接到测试服务器并等待连接成功
    private fun connectAndWait() {
        val connectedLatch = CountDownLatch(1)

        tcpClient.setStatusListener(object : TCPClient.OnStatusListener {
            override fun onStatus(isConnected: Boolean, error: String?) {
                if (isConnected) {
                    connectedLatch.countDown()
                }
            }
        })

        tcpClient.connect(TEST_IP, TEST_PORT, 1000)
        assertTrue("连接超时", connectedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))
    }

// 服务器端伪代码示例
    fun startServer() {
        Thread {
            try {
                val serverSocket = ServerSocket(9001)
                Log.d("Server", "服务器启动，监听端口9001")

                while (true) {
                    val clientSocket = serverSocket.accept()
                    Log.d("Server", "客户端连接: ${clientSocket.inetAddress}")

                    val inputStream = clientSocket.getInputStream()
                    val outputStream = clientSocket.getOutputStream()

                    // 读取客户端数据
                    val buffer = ByteArray(1024)
                    val bytesRead = inputStream.read(buffer)
                    if (bytesRead > 0) {
                        val request = String(buffer, 0, bytesRead)
                        Log.d("Server", "收到数据: $request")

                        // 回显数据给客户端
                        outputStream.write(buffer, 0, bytesRead)
                        outputStream.flush()
                    }

                    clientSocket.close()
                }
            } catch (e: IOException) {
                Log.e("Server", "服务器错误: ${e.message}")
            }
        }.start()
    }


}